include([
         'renderers.All'
         , 'com.unknown.GameWindow'
         , 'PathBuilder'], 
function(){
	
	declare('PathPainter')
	
	PathPainter = function(config){
		if( config ){
			this.pathId  = config.pathId  || '';
			this._builder = config.builder || new PathBuilder();
			this._baseUrl = config.baseUrl || '';
			this.fill     = config.fill === false ? false : true;
			this.fillOnTop = config.fillOnTop ? true : false;
			this.border   = config.border === false ? false : true;
		}else{
			this.pathId   = '';
			this._baseUrl = '';
			this.fill   = true;
			this.fillOnTop = false;
			this.border = true;
			this._builder = new PathBuilder();
		}
	};
	
	PathPainter.prototype = {
		paint : function(cell){
			this._clean(cell);
			if( this.fill && !this.fillOnTop )
				this._fill(cell);
			if( this.border )
				this._border(cell);
			if( this.fill && this.fillOnTop )
				this._fill(cell);
		},
		erase : function(cell){
			iterate(cell.images, function(i){i.remove();})
		},
		_createPathImage : function(src, cell, zindex){
			var contents = $(document.createElement('img'));
			contents.attr('src', this._baseUrl + src+'.png');
			contents.css('position', 'absolute');
			contents.css('top', (cell.row)*15+cell.owner._offsetY);
			contents.css('left', (cell.col)*35+cell.owner._offsetX);
			contents.css('z-index', (cell.row*100 + cell.col)+500);
			cell.owner.container.append(contents);
			//$('#floor').append(contents);
			if(!cell.images) cell.images = [];
			cell.images.push( contents );
		},		
		_fill : function(cell){
			var hasPath = this._getCellsWithPaths(cell);
			var pathId = this.pathId;
			if( hasPath.length ){
				cell.path = {id:pathId, solo:false};
				hasPath.push( cell );								
				this._rebuildFill(hasPath);
			}
		},
		_rebuildFill : function(items){
			var pathBuilder = this._builder;
			var scope = this;
			var pathId = this.pathId;
			iterate(items, function(item){
				var borders = pathBuilder.matchOpenBorders(item, PathBuilder.HEX_FILL);
				iterate(borders, function(border){
					if( border.id ) scope._createPathImage('images/paths/'+pathId+'/out_'+border.id, item);
				});
			});
		},
		_border : function(cell){
			var hasPath = this._getCellsWithPaths(cell);
			var pathBuilder = this._builder;
			var scope = this;
			var pathId = this.pathId;
			if( hasPath.length == 0 ){
				cell.path = {id:pathId, solo:true};
			}else{
				cell.path = {id:pathId, solo:false};
				hasPath.push( cell );								
				this._rebuildBorders(hasPath);
			}
		},
		_rebuildBorders : function(items){
			var pathBuilder = this._builder;
			var scope = this;
			var pathId = this.pathId;
            //Assign borders
			iterate(items, function(item){
                item.borders = pathBuilder.buildPath(item);
			});
            //Determine curve experimenting
            /*
            iterate(items, function(item){
                var neighbors = scope._getCellsWithPaths(item);
                var _in = 0, _out = 0;
                iterate(neighbors, function(neighbor){
                    iterate(neighbor.borders, function(border){
                        if( border.curve == 'in' ) _in++;
                        if( border.curve == 'out') _out++;
                    })
                });
                if( _in > _out ){
                    if(item.borders[0] && (item.borders[0].id == 'v-r' || item.borders[0].id == 'v-l' ))
                        console.log(item.borders[0].id + " Curving in " + _in + " vs " + _out);
                    item.curve = 'in';
                }else if(_out > _in){
                    if(item.borders[0] && (item.borders[0].id == 'v-r' || item.borders[0].id == 'v-l' ))
                        console.log(item.borders[0].id + " Curving out " + _in + " vs " + _out);
                    item.curve = 'out';
                }else{
                    if(item.borders[0] && (item.borders[0].id == 'v-r' || item.borders[0].id == 'v-l' ))
                        console.log(item.borders[0].id + " Curve unknown " + _in + " vs " + _out);
                    item.curve = null;
                }
            });
            */
            //Paint borders
            iterate(items, function(item){
                var borders = item.borders;
                iterate(borders, function(border){
                    var imageSuffix = null;

                    if( item.curve && !border.curve ){
                        if( item.curve == 'out' )
                            imageSuffix = border.outer;
                        else
                            imageSuffix = border.inner;
                    }
                    else{
                        imageSuffix = border.id;
                    }
                    if( imageSuffix )
                        scope._createPathImage('images/paths/'+pathId+'/out_'+imageSuffix, item);
                });
            });
		},
		_clean : function(cell){
			var hasPath = this._getCellsWithPaths(cell);
			hasPath.push(cell);
			iterate(hasPath, function(item){
				if( item.images ){
					iterate(item.images, function(i){i.remove();})
				}
			});
		},
		_getCellsWithPaths : function(cell){
			var grid = cell.owner;
			var neighbors = grid.getNeighbors(cell);
			var hasPath = [];
			iterate(neighbors, function(item, index){
				if( !item.path ) return;
				hasPath[index] = item;
			});
			return hasPath;
		}
		
	};
})